
import time

import uiautomator2 as u2


class Sun_uiautomator2:

    def __init__(self):
        pass

    # 连接安卓设备 传入adb devices的id号  或者 http://192.168.2.3格式的目标设备ip地址
    def connect_device(self,device_id):
        return u2.connect(device_id)

    # 删除apk，传入包名  包名可通过 logcat | grep package 或者 Displayed 然后点击/关闭目标应用程序 查看log输出获得
    # com.project.app.zqv2
    def uninstall_apk(self,device,apk_package_name):
        device.app_uninstall(apk_package_name)

    # 安装apk 传入apk路径
    def install_apk(self,device,apk_path):
        device.app_install(apk_path)

    # 打开apk
    def open_apk(self,device,apk_package_name):
        device.app_start(apk_package_name)

    # 关闭apk
    def close_apk(self,device,apk_package_name):
        device.app_stop(apk_package_name)

    # 获取当前正在前台显示的apk名称   什么都没打开时 显示桌面的包名  桌面也是一个apk
    def get_current_show_apk(self,device):
        return device.app_current()

    # 获取正在运行的所有apk  包括在前台运行的 后台运行的 和不在后台的所有系统服务apk
    def get_all_running_apk(self,device):
        return device.app_list_running()

    # 获取一个apk的版本信息
    def get_apk_version(self,device,apk_package_name):
        return device.app_info(apk_package_name)

    # 清除一个apk的缓存  回到第一次打开时的状态
    def clear_apk_data(self,device,apk_package_name):
        device.app_clear(apk_package_name)

    # 获取已经安装的所有apk 包括桌面上没有应用图标的那种
    def get_all_installed_apk(self,device):
        return device.app_list()

    # 获取设备信息  当前正在展示的apk包名 显示器宽度高度 当前竖向横向显示 屏幕是否打开 产品名称  sdk版本等等
    def get_device_info(self,device):
        return device.info

    # 获取当前设备的宽高信息
    def get_device_screen_size(self,device):
        return device.window_size()

    # 截屏
    def screen_shot_device_screen(self,device,save_path):
        current_time = time.strftime("%Y_%m_%d_%H_%M_%S", time.localtime(time.time()))
        device.screenshot(f"{save_path}\\android_device_screenshot_{current_time}.png")

    # 获取当前屏幕开启状态
    def get_current_screen_power(self,device):
        return device.info.get('screenOn')

    # 唤醒屏幕
    def awake_screen(self,device):
        device.unlock()

    # 往设备中推文件
    def push_file_to_device(self,device,local_file_path,target_path):
        device.push(local_file_path,target_path)

    # 从设备中拉文件
    def recv_file_from_device(self,device,target_path_file,local_path):
        device.push(target_path_file,local_path)

    # 打开下拉通知 (完全展开)
    def open_drop_notice(self,device):
        device.open_quick_settings()

    # 按下电源键
    def press_power_key(self,device):
        device.press('power')

    # 按下音量增加键
    def press_volume_up_key(self,device):
        device.press('volume_up')

    # 按下音量减少键
    def press_volume_down_key(self,device):
        device.press('volume_down')

    # 按下静音键
    def press_volume_stop_key(self,device):
        device.press('volume_mute')

    # 按下最近程序键
    def press_recent_key(self,device):
        device.press('recent')

    # 按下返回键
    def press_back_key(self,device):
        device.press('back')

    # 按下home键
    def press_home_key(self,device):
        device.press('home')

    # 点击屏幕指定位置
    def click_screen_position(self,device,x,y):
        device.click(x, y)

    # 长按指定位置
    def long_click_screen_position(self,device,x,y,time):
        device.long_click(x,y,time)

    # 从一个位置划到另一个位置  如果滑动时间过长 和 按住拖拽效果可能一致
    def swipe_screen(self,device,start_x,start_y,end_x,end_y,time=0.1):
        device.swipe(start_x, start_y, end_x, end_y, time)

    # 按住从一个位置划到另一个位置松开
    def drag_screen(self,device,start_x,start_y,end_x,end_y,time=0.1):
        device.drag(start_x, start_y, end_x, end_y, time)

    # 左滑屏幕
    def left_swipe_screen(self,device,time=0.1):
        width,height = self.get_device_screen_size(device)
        center_y = height / 2
        start_x = width * 0.8
        end_x = width * 0.2
        device.swipe(start_x, center_y, end_x, center_y, time)

    # 右滑屏幕
    def right_swipe_screen(self,device,time=0.1):
        width,height = self.get_device_screen_size(device)
        center_y = height / 2
        start_x = width * 0.2
        end_x = width * 0.8
        device.swipe(start_x, center_y, end_x, center_y, time)

    # 上滑屏幕
    def up_swipe_screen(self,device,time=0.1):
        width,height = self.get_device_screen_size(device)
        center_x = width / 2
        start_y = height * 0.8
        end_y = height * 0.2
        device.swipe(center_x, start_y, center_x, end_y, time)

    # 下滑屏幕
    def down_swipe_screen(self,device,time=0.1):
        width,height = self.get_device_screen_size(device)
        center_x = width / 2
        start_y = height * 0.2
        end_y = height * 0.8
        device.swipe(center_x, start_y, center_x, end_y, time)


    # resourceid属性定位元素 id匹配
    # id属性 不唯一移动端好几个元素可能都是相同的resourceid
    # 与selenium一样 元素在显示器上不可见 或者 被其他元素挡住 都找不到元素
    # 查找元素时 不一定非得看见元素才能找到  只要当前页面中确实存在元素  就可以找到,对元素进行操作时 必须在显示器内看见才行
    def find_elements_by_id(self,device,find_script):
        return device(resourceId=find_script)

    # text属性定位元素   文本属性匹配
    # all_str_equal为true 代表全匹配  为false 代表部分匹配
    def find_elements_by_text(self,device,find_script,is_all_str_equal=True):
        if is_all_str_equal:
            return device(text=find_script)
        else:
            return device(textContains=find_script)

    # content-desc属性定位元素   描述信息匹配
    # all_str_equal为true 代表全匹配  为false 代表部分匹配
    def find_elements_by_description(self,device,find_script,all_str_equal=True):
        if all_str_equal:
            return device(description=find_script)
        else:
            return device(descriptionContains=find_script)


    # xpath方式查找元素  最推荐
    # //android.view.ViewGroup/android.widget.TextView[3]
    def find_elements_by_xpath(self,device,find_script):
        return device.xpath(find_script)



    # 根据一个元素位置和查找方向 以及目标元素的text属性 定位
    # 方向不能偏差太大  元素在右上 往正右方向找不到
    def find_elements_by_element(self,element,direction,find_script):
        if direction.lower() == "left":
            return element.left(text=find_script)
        elif direction.lower() == "right":
            return element.right(text=find_script)
        elif direction.lower() == "down":
            return element.down(text=find_script)
        elif direction.lower() == "up":
            return element.up(text=find_script)
        else:
            print(f"错误的查找方向{direction}")

    # 元素点击操作
    def click_element(self,element):
        element.click()

    # 元素长按操作
    def long_click_element(self,element,time):
        element.long_click(time)

    # 检查元素是否存在
    # 如果当前页面确实存在元素，但此时显示器上看不见  会认为元素不存在
    def judge_element_is_exist(self,element):
        return element.exists

    # 元素输入内容
    def input_data_to_element(self,element,data):
        element.send_keys(data)

    # 清空元素输入内容
    def clear_element_text_data(self,element):
        element.clear_text()

    # 设置全局等待
    def set_global_await(self,device,time):
        device.implicitly_wait(time)






